# 求任意阶数矩阵的逆矩阵
# 创建时间：2025.10.22
# 创建者：郭吉喆

from fractions import Fraction

ROW = {}  # 行的集合
n = int(input("请输入矩阵的阶数--->"))
for i in range(1, n + 1):
    # i = str(i)
    ROW[i] = []
# print(ROW)

# 输入原矩阵的数据
row = 1
while row <= n:
    cnt = 1
    while cnt <= n:
        ROW[row].append(input(f"输入第{row}行 第{cnt}列的数据--->"))
        cnt += 1
    row += 1
# print(ROW)

# 添加单位矩阵
row = 1
while row <= n:
    cnt = 1
    while cnt <= n:
        ROW[row].append(0)  # 构造零矩阵
        cnt += 1
    ROW[row][n + row - 1] = 1 # 在零矩阵中添加1
    row += 1
# print(ROW)

# 考虑到矩阵运算，需将列表所有元素转换为int类型
for i in range(1, n + 1):
    ROW[i] = list(map(int, ROW[i]))
# print(ROW)

# 初等变换（函数定义倍法变换，换法变换以及消法变换）
def multiple(row, mult):
    ROW[row] = list(map(lambda x: x * mult, ROW[row]))

def change(row_1, row_2):
    row_mid = ROW[row_1]
    ROW[row_1] = ROW[row_2]
    ROW[row_2] = row_mid

def minus(row_o, row_c, mult): # 不动行，运算行，倍数
    for i in range(0, 2 * n):
        ROW[row_c][i] += ROW[row_o][i] * mult
# minus(1, 2, -1)
# print(ROW)

# a.比较各行首位数，取最小数并化为1
# min_row = 1
# min_num = ROW[1][0]
# for i in range(1, n + 1):
#     if ROW[i][0] < min_num:
#         min_row = i
#         min_num = ROW[i][0]
# multiple(min_row, 1.0 / min_num) # 化为1
# # print(ROW)
# # print(min_num)
#
# # b.换法+消法变换，构造单位矩阵第一列
# change(min_row, 1)
# for i in range(2, n + 1):
#     minus(1, i, -ROW[i][0])
# print(ROW)

# 重复ab步骤
for i in range(1, n + 1):
    min_row = 0
    for t in range(i, n + 1):  # 检索非零数
        if ROW[t][i - 1] != 0:
            min_row = t
            min_num = ROW[t][i - 1]
            change(i, min_row)
            break
    if  min_row == 0:
        raise Exception("该矩阵行列式为零")
    for j in range(i, n + 1):  # a.比较各行非零数，取绝对值最小数化为1
        if ROW[j][i - 1] == 0:
            continue
        if abs(ROW[j][i - 1]) < abs(min_num):
            min_row = j
            min_num = ROW[j][i - 1]
            change(i, min_row)
    # print(ROW)
    # print(i,min_num)
    multiple(i, Fraction(1.0 / min_num))
    # print(ROW)

    for k in range(1, n + 1):  # b.消法变换，在列上构造单位矩阵
        if k == i:
            continue
        minus(i, k, -ROW[k][i - 1])
    # print(ROW)
# print(ROW)

# 删去单位矩阵，得到逆矩阵
for i in range(1, n + 1):
    for j in range(0, n):
        ROW[i].remove(ROW[i][0])
# print(ROW)

# 输出逆矩阵（根据实际需要输出小数/分数）
pr = input("输入你期望的输出格式"
           "(小数-->a；分数-->b)--->")
while True:
    if pr == 'a':
        print("该矩阵的逆矩阵为：")
        for i in range(1, n + 1):
            ROW[i] = list(map(float, ROW[i]))
        for i in range(1, n + 1):
            for j in range(0, n):
                print(f"{ROW[i][j]:10.4f}",end="") # 总宽度.保留小数位数
            print("\n")
        break
    elif pr == 'b':
        print("该矩阵的逆矩阵为：")
        for i in range(1, n + 1):
            for j in range(0, n):
                print(ROW[i][j], end="\t")
            print("\n")
        break
    else:
        pr = input("--->")
